package mspbots.data.tl.prod.jira.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.data.tl.base.AbstractBaseServiceImpl;
import mspbots.data.tl.entity.ResultMessageModel;
import mspbots.data.tl.prod.jira.mapper.JiraIssueMapper;
import mspbots.data.tl.prod.jira.mapper.JiraTeamMapper;
import mspbots.data.tl.prod.jira.model.JiraIssue;
import mspbots.data.tl.prod.jira.model.JiraTeam;
import mspbots.data.tl.prod.jira.service.JiraIssueService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author Jay.Yang
 */

@Service
@Log4j2
@DS("master")
@RequiredArgsConstructor
public class JiraIssueServiceImpl extends AbstractBaseServiceImpl<JiraIssueMapper, JiraIssue>
        implements JiraIssueService {

    private final JiraTeamMapper jiraTeamMapper;

    @Override
    public void sync(ResultMessageModel model) {
        if (ObjectUtils.isEmpty(model.getEntity()) || !ResultMessageModel.MessageModelAction.ADD.equals(model.getAction())) {
            log.error("jira.issue.tl entry is null,or Action No Add");
            return;
        }
        JsonNode fields = model.getEntity().get("fields");
        JiraIssue data = JiraIssue.builder()
                .issueId(model.getEntity().get("id").asLong())
                .key(model.getEntity().get("key").asText())
                .summary(fields.get("summary").asText())
                .description(fields.get("description").isNull() ? null : fields.get("description").asText())
                .epicLink(!ObjectUtils.isEmpty(fields.get("customfield_10101")) && !fields.get("customfield_10101").isNull()
                        ? fields.get("customfield_10101").asText() : null)
                .storyPoints(!ObjectUtils.isEmpty(fields.get("customfield_10106")) && !fields.get("customfield_10106").isNull()
                        ? fields.get("customfield_10106").asDouble() : null)
                .priorityName(!ObjectUtils.isEmpty(fields.get("priority")) ? fields.get("priority").get("name").asText() : null)
                .typeName(!ObjectUtils.isEmpty(fields.get("issuetype")) ? fields.get("issuetype").get("name").asText() : null)
                .creatorDisplayName(!ObjectUtils.isEmpty(fields.get("creator")) ? fields.get("creator").get("displayName").asText() : null)
                .projectName(!ObjectUtils.isEmpty(fields.get("project")) ? fields.get("project").get("name").asText() : null)
                .dueDate(!ObjectUtils.isEmpty(fields.get("duedate")) && !fields.get("duedate").isNull()
                        ? LocalDate.parse(fields.get("duedate").asText()) : null)
                .assigneeDisplayName(!ObjectUtils.isEmpty(fields.get("assignee")) && !fields.get("assignee").isNull()
                        ? fields.get("assignee").get("displayName").asText() : null)
                .statusName(!ObjectUtils.isEmpty(fields.get("status")) ? fields.get("status").get("name").asText() : null)
                .createTime(!ObjectUtils.isEmpty(fields.get("created"))
                        ? LocalDateTime.parse(fields.get("created").asText().substring(0,19), DateTimeFormatter.ISO_DATE_TIME) : null)
                .updateTime(!ObjectUtils.isEmpty(fields.get("updated"))
                        ? LocalDateTime.parse(fields.get("updated").asText().substring(0,19), DateTimeFormatter.ISO_DATE_TIME) : null)
                .syncTime(LocalDateTime.now())
                .build();
        data.setTenantCode(model.getTenantId());
        if (!ObjectUtils.isEmpty(fields.get("fixVersions"))){
            Iterator<JsonNode> fixVersions = fields.get("fixVersions").elements();
            List<String> fixVersionsNames = new ArrayList<>();
            while (fixVersions.hasNext()){
                fixVersionsNames.add(fixVersions.next().get("name").asText());
            }
            data.setFixVersionsNames(StringUtils.join(fixVersionsNames,","));
        }
        if (!ObjectUtils.isEmpty(fields.get("customfield_10100")) && !fields.get("customfield_10100").isNull()){
            String sprint = fields.get("customfield_10100").elements().next().asText();
            sprint = sprint.substring(sprint.indexOf(",name=") + 6);
            data.setSprintName(sprint.substring(0, sprint.indexOf(",")));
        }
        if (!ObjectUtils.isEmpty(fields.get("customfield_10300")) && !fields.get("customfield_10300").isNull()){
            Long teamId = fields.get("customfield_10300").asLong();
            JiraTeam jiraTeam = jiraTeamMapper.selectOne(Wrappers.<JiraTeam>lambdaQuery()
                    .eq(JiraTeam::getTenantCode, data.getTenantCode())
                    .eq(JiraTeam::getTeamId, teamId)
                    .last("limit 1"));
            data.setTeamName(!ObjectUtils.isEmpty(jiraTeam) ? jiraTeam.getTitle() : null);
        }

        JiraIssue dbData = super.baseMapper.selectOne(Wrappers.<JiraIssue>lambdaQuery()
                .eq(JiraIssue::getTenantCode, data.getTenantCode())
                .eq(JiraIssue::getIssueId, data.getIssueId())
                .last("limit 1"));
        if (ObjectUtils.isEmpty(dbData)) {
            super.baseMapper.insert(data);
        } else {
            data.setId(dbData.getId());
            super.baseMapper.updateById(data);
        }
    }
}
